package com.inspur.edp.formserver.viewmodel.webapi;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.das.commonmodel.util.HandleAssemblyNameUtil;
import com.inspur.edp.cef.designtime.api.dtconsistencycheck.ConsistencyCheckEventMessage;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.common.ConvertUtils;
import com.inspur.edp.formserver.viewmodel.common.ValueHelpConfig;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.actioneventargs.ChangingVoActionCodeEventArgs;
import com.inspur.edp.formserver.vmmanager.helpconfig.HelpConfigFilterSortHandler;
import com.inspur.edp.formserver.vmmanager.service.WebControllerService;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.actioneventargs.*;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.entityeventargs.*;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.fieldeventargs.*;
import com.inspur.edp.formserver.vmmanager.validate.model.ViewModelChecker;
import com.inspur.edp.formserver.vmmanager.voguide.VoGuideUtil;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.metadata.businesstype.api.MdBizTypeMappingService;
import io.iec.edp.caf.boot.context.CAFContext;
import java.util.HashMap;

import com.inspur.edp.formserver.vmmanager.vmdtconsistencycheckevent.VmDtConsistencyCheckEventBroker;
import com.inspur.lcm.metadata.logging.LoggerDisruptorQueue;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.List;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("")
@Produces(MediaType.APPLICATION_JSON)
public class VMCodeGenController {
  @Path("checkvo")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public void checkKeywords(String jsonObject) {
    WebControllerService.getInstance().checkKeywords(jsonObject);
  }

  @Path("convertBizEntity")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBizEntity(String jsonObject) {
    if (CheckInfoUtil.checkNull(jsonObject)) {
      throw new RuntimeException("请传入有效Json对象.");
    }

    ObjectMapper mapper = new ObjectMapper();
    try {
      JsonNode jsonNode = mapper.readTree(jsonObject);
      JsonNode bizEntityJsonNode = jsonNode.get("bizEntityJson");
      CheckInfoUtil.checkNessaceryInfo("bizEntityJson", bizEntityJsonNode);
      JsonNode bePkgNameJsonNode = jsonNode.get("bePkgName");
      CheckInfoUtil.checkNessaceryInfo("bePkgName", bePkgNameJsonNode);
      JsonNode beIdJsonNode = jsonNode.get("beId");
      CheckInfoUtil.checkNessaceryInfo("beId", beIdJsonNode);
      JsonNode voGeneratingAssemblyJsonNode = jsonNode.get("voGeneratingAssembly");
      CheckInfoUtil.checkNessaceryInfo("voGeneratingAssembly", voGeneratingAssemblyJsonNode);

      String bizEntityJson = bizEntityJsonNode.textValue();
      String bePkgName = bePkgNameJsonNode.textValue();
      String beId = beIdJsonNode.textValue();
      String voGeneratingAssembly = voGeneratingAssemblyJsonNode.textValue();

      return convertBizEntityToViewModel(bizEntityJson, bePkgName, beId, voGeneratingAssembly);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }


  @Path("createVoRt")
  @PUT
  public String createVoRt(String jsonObject) {
    ObjectMapper mapper = new ObjectMapper();
    try {
      JsonNode jsonNode = mapper.readTree(jsonObject);

      JsonNode basicInfoNode = jsonNode.get("basicInfo");
      CheckInfoUtil.checkNessaceryInfo("Vo基本信息", basicInfoNode);
      String voCode = basicInfoNode.get("code").textValue();
      String voName = basicInfoNode.get("name").textValue();

      JsonNode beNode = jsonNode.get("be");
      CheckInfoUtil.checkNessaceryInfo("源业务实体", beNode);
      GspBusinessEntity be = mapper.readValue(beNode.toString(), GspBusinessEntity.class);
      CheckInfoUtil.checkNessaceryInfo("源业务实体", be);

      GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(be.getID());
      String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
      String bizObjectId = beMetadata.getHeader().getBizobjectID();

      JsonNode configsArrayNode = jsonNode.get("configs");
      HashMap<String, String> configMap = new HashMap<>();
      if (configsArrayNode != null && configsArrayNode.size() != 0) {
        for (JsonNode configNode : configsArrayNode) {
          String key = configNode.get("key").textValue();
          String value = configNode.get("value").textValue();
          configMap.put(key, value);
        }
      }
      String billCategoryId = null;
      JsonNode billCategoryInfo = jsonNode.get("billCategoryId");
      if(CheckInfoUtil.checkNull(billCategoryInfo)) {
        billCategoryId = billCategoryInfo.textValue();
      }

      GspViewModel vo = VoGuideUtil.getInstance()
          .createVo(be, configMap, beNameSpace, HandleAssemblyNameUtil
              .convertToJavaPackageName(beNameSpace));
      vo.setCode(voCode);
      vo.setName(voName);
      String voId = VoGuideUtil.getInstance().saveVoRt(vo, bizObjectId, beNameSpace);
      MdBizTypeMappingService service=SpringBeanUtils.getBean(MdBizTypeMappingService.class);
      if(billCategoryId == null)
        service.save(configMap.get("billCategoryId"),voId);
      else
        service.save(billCategoryId,voId);

      return new ObjectMapper().writeValueAsString(voId);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  @Path("checkVoConfigIdRt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public void checkVoConfigIdRt(String jsonObject) {
    ObjectMapper mapper = new ObjectMapper();
    try {
      JsonNode jsonNode = mapper.readTree(jsonObject);
      JsonNode beIdNode = jsonNode.get("beId");
      CheckInfoUtil.checkNessaceryInfo("源业务实体元数据ID", beIdNode);
      String beId = beIdNode.textValue();
      CheckInfoUtil.checkNessaceryInfo("源业务实体元数据ID", beId);

      JsonNode voCodeNode = jsonNode.get("voCode");
      CheckInfoUtil.checkNessaceryInfo("VO编号", voCodeNode);
      String voCode = voCodeNode.textValue();
      CheckInfoUtil.checkNessaceryInfo("VO编号", voCode);

      GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(beId);
      String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
      GspViewModel vo = ConvertUtils
          .convertToViewModel((GspBusinessEntity) beMetadata.getContent(), beNameSpace,
              beMetadata.getHeader().getId(),
              HandleAssemblyNameUtil.convertToJavaPackageName(beNameSpace));
      vo.setCode(voCode);
      VoGuideUtil.getInstance().checkBeforeSave(vo.getGeneratedConfigID(), vo.getId(), vo.getCode());
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  @Path("handleHelpConfigFilterSort")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public ValueHelpConfig handleHelpConfigFilterSortCondition(String jsonObject) {
    ObjectMapper mapper = new ObjectMapper();
    try {
      JsonNode jsonNode = mapper.readTree(jsonObject);
      JsonNode helpConfigNode = jsonNode.get("helpConfig");
      CheckInfoUtil.checkNessaceryInfo("helpConfig", helpConfigNode);
      ValueHelpConfig config = mapper.readValue(helpConfigNode.textValue(), ValueHelpConfig.class);
      JsonNode filterConditionNode = jsonNode.get("filterCondition");
      JsonNode sortConditionNode = jsonNode.get("sortCondition");
      JsonNode pathNode = jsonNode.get("path");
      HelpConfigFilterSortHandler.getInstance(config, pathNode.textValue())
          .handleConfigFilterAndSort(
              filterConditionNode.textValue(), sortConditionNode.textValue());
      return config;
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  private String convertBizEntityToViewModel(String bizEntityJson, String bePkgName, String beId,
      String voGeneratingAssembly) {
    GspBusinessEntity be = null;
    try {
      be = new ObjectMapper().readValue(bizEntityJson, GspBusinessEntity.class);
      GspViewModel vm = ConvertUtils.convertToViewModel(be, bePkgName, beId, voGeneratingAssembly);
      // 联动vo的关联带出字段枚举信息
//            LinkBeUtils linkBeUtils = new LinkBeUtils();
//            linkBeUtils.LinkBeRefElements(vm);

      return new ObjectMapper().writeValueAsString(vm);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("元数据序列化失败", e);
    }
  }




    /**
     * 删除Vo节点
     */
    @Path("vmDtConsistencyCheck/removingViewObject")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public RemovingViewObjectEventArgs removingViewObject(RemovingViewObjectEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireRemovingViewObject(args);

        if(args.getEventMessages().size() != 0){
            BefConsistencyCheckMessage(args.getEventMessages(),"请先解除该Vo节点的依赖和关联信息");
        }
        return args;
    }

    /**
     * 修改BizEntityCode
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingViewObjectCode")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingViewObjectCodeEventArgs changingViewObjectCode(ChangingViewObjectCodeEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingViewObjectCode(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该Vo节点的依赖和关联信息");
        }
        return args;
    }
    /**
     * 删除Vo 字段
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/removingVoField")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public RemovingVoFieldEventArgs removingVoField(RemovingVoFieldEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireRemovingVoField(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该Vo字段的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改Vo字段数据类型
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldDataType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldDataTypeEventArgs changingVoFieldDataType(ChangingVoFieldDataTypeEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldDataType(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该Vo字段的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改Vo字段objectType
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldObjectType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldObjectTypeEventArgs changingVoFieldObjectType(ChangingVoFieldObjectTypeEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldObjectType(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该Vo字段的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改Vo字段标签
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldLabelId")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldLabelIdEventArgs changingVoFieldLabelId(ChangingVoFieldLabelIdEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldLabelId(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该Vo字段的依赖和关联信息");
        }
        return args;
    }

    /**
     * 修改动作编号
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionCode")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionCodeEventArgs changingVoActionCode(ChangingVoActionCodeEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionCode(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该动作的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionParams")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionParamsEventArgs changingVoActionParams(ChangingVoActionParamsEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionParams(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该动作的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改集合类型
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionCollectType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionCollectTypeEventArgs changingVoActionCollectType(
        ChangingVoActionCollectTypeEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionCollectType(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该动作的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionReturn")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionReturnEventArgs changingVoActionReturn(ChangingVoActionReturnEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionReturn(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该动作的依赖和关联信息");
        }
        return args;
    }
    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/deletingVoAction")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public DeletingVoActionEventArgs deletingVoAction(DeletingVoActionEventArgs args){
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireDeletingVoAction(args);

        if(args.eventMessages.size() != 0){
            BefConsistencyCheckMessage(args.eventMessages, "请先解除该动作的依赖和关联信息");
        }
        return args;
    }
    /**
     * 控制台输出BEF Warnings
     *
     * @param messages
     */
    public void BefConsistencyCheckMessage(List<ConsistencyCheckEventMessage> messages,String
        suffix){
        StringBuilder befWarnings = new StringBuilder();
        if (messages.size() > 0)
            messages.forEach(message->{
                befWarnings.append(message.getMessage());
            });
        befWarnings.append(suffix);
        String currentUerId = CAFContext.current.getUserId();
        if (currentUerId == null || currentUerId.equals("")) {
          throw new RuntimeException("获取当前用户ID为空");
        }
        LoggerDisruptorQueue.publishEvent("[BEF Warning]:" + befWarnings.toString(),currentUerId);
    }
}
